<?php
/*
* Kusht Mud.
* ----
* The MIT License
* Copyright (c) 2010 Andrew Tutt
* ----
*/

/* World Class
*
*
* Govern's Worldwide Game State Information (Dynamic)
* Including:
* :: Who's Logged In
* :: The list of game rooms
*/


class World {
	public static $char_list = array();
	public static $expiring_items = array();
	
	// Loaded at startup
	public static $room_list = array();
	public static $affects = array(); 		// Holds all the game's possible affects (loaded into database, easily extended);
	public static $spells  = array();			// Holds all the game's possible spells (see above);
	public static $special_attacks = array(); // For Special Attacks
	
	/* We use an EXTREMELY efficient checking model, wherein we use sorted information to 
	*  significantly reduce the number of automated checks that are performed in the game.
	*  we do this by governing lots of data here. For instance, affects are only checked
	*  if they are actually affecting something in the game, and they are checked from
	*  closest to expiration to farthest, breaking the check when the next item in the list is unexpired.
	*  We use this same method repeatedly game-wide. */
	public static function Update() {
		// Check all Affects for timeouts
		foreach(World::$affects as $affect) {
			if(!key($affect->affected)) { break; }
			if(key($affect->affected) > microtime(1)) { break; }
			$affect->expire();
		}
		
		// Check rooms for updates
		foreach(World::$room_list as $room) {
			if($room->execute_code == "") { break; } // We do this because we have sorted the rooms in a way that allows this
			$room->do_execute();
		}
		
		// Check all Objects for timeouts
		// Needs to be sorted for earliest expiration to latest
		foreach(World::$expiring_items as $item) {
			$item->expire();
		}
	}
	
	public static function get_char_world($queryinguser,$targetstr) {
		$userinroom = $queryinguser->in_room()->get_char($queryinguser, $targetstr);
		if ($userinroom) {
			return $userinroom;
		}
		foreach(World::$char_list as $char) {
			if (stripos($char->name,$targetstr)!==FALSE) { return $char; }
		}
		return false;
	}
	
	public static function add_char_to_world($user) {
		array_push(World::$char_list,$user);
		// Throw off a trigger to update the global "who" list
		World::whoisUpdate();
	}
	
	public static function rmv_char_from_world($user) {
		array_del_elem(World::$char_list,$user);
		// Throw off a trigger to update the global "who" list
		World::whoisUpdate();
	}
	
	public static function whoisUpdate() {
		foreach(World::$char_list as $person) {
			clientHandler::whois($person);
		}
	}
	
	// LOW LEVEL FUNCTIONS (USED FOR SORTING)
	
	function sortAffects() {
		usort(World::$affects,"World::compareAffectsExpirations");
	}
	
	function compareAffectsExpirations($a,$b) {
		if(current($a->affected)) { $a = key($a->affected); }
		else { return 1; }
		if(current($b->affected)) { $b = key($b->affected); }
		else { return -1; }
		return ($a < $b) ? -1 : 1;
	}
	
	function sortRooms() {
		usort(World::$room_list,"World::compareObjIntervals");
	}
	
	function compareObjIntervals($a,$b) {
		if($a->execute_code == "") { return 1; }
		if($b->execute_code == "") { return -1; }
		return ($a->interval_length < $b->interval_length) ? -1 : 1;		
	}
	
}

?>